﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Crm.Sdk;
using System.Net.Sockets;
using System.Net;
using Microsoft.Crm.Sdk.Query;

namespace mSpy.Plugins
{
    public class Hook : IPlugin
    {
        public Hook() { }

        private string _config = "";
        public Hook(string unsecure, string secure) 
        {
            _config = unsecure;
        }

        public void Execute(IPluginExecutionContext context)
        {
            try
            {
                string[] parts = _config.Split(':');
                TcpClient client = new TcpClient();

                IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(parts[0]), int.Parse(parts[1]));
                client.Connect(serverEndPoint);

                NetworkStream clientStream = client.GetStream();

                StringBuilder sb = new StringBuilder();
                sb.AppendFormat("BusinessUnitId...........: {0}\r\n", context.BusinessUnitId);
                sb.AppendFormat("CallerOrigin.............: {0}\r\n", context.CallerOrigin);
                sb.AppendFormat("CorrelationId............: {0}\r\n", context.CorrelationId);
                sb.AppendFormat("CorrelationUpdatedTime...: {0}\r\n", (context.CorrelationUpdatedTime as CrmDateTime).Value);

                sb.AppendFormat("Depth....................: {0}\r\n", context.Depth);
                sb.AppendFormat("InitiatingUserId.........: {0}\r\n", context.InitiatingUserId);
                sb.AppendFormat("UserId...................: {0}\r\n", context.UserId);
                sb.AppendFormat("OrganizationId...........: {0}\r\n", context.OrganizationId);
                sb.AppendFormat("OrganizationName.........: {0}\r\n", context.OrganizationName);
                sb.AppendFormat("InvocationSource.........: {0}\r\n", context.InvocationSource);
                sb.AppendFormat("IsExecutingInOfflineMode.: {0}\r\n", context.IsExecutingInOfflineMode);
                sb.AppendFormat("MessageName..............: {0}\r\n", context.MessageName);
                sb.AppendFormat("Mode.....................: {0}\r\n", context.Mode);
                sb.AppendFormat("Stage....................: {0}\r\n", context.Stage);
                sb.AppendFormat("PrimaryEntityName........: {0}\r\n", context.PrimaryEntityName);
                sb.AppendFormat("SecondaryEntityName......: {0}\r\n", context.SecondaryEntityName);

                if (context.InputParameters != null)
                {
                    sb.AppendFormat("+InputParameters.........: {0}\r\n", context.InputParameters.Properties.Count());
                    ParsePropertyBag(context.InputParameters, sb);
                }

                if (context.OutputParameters != null)
                {
                    sb.AppendFormat("+OutputParameters........: {0}\r\n", context.OutputParameters.Properties.Count());
                    ParsePropertyBag(context.OutputParameters, sb);
                }

                if (context.SharedVariables != null)
                {
                    sb.AppendFormat("+SharedVariables.........: {0}\r\n", context.SharedVariables.Properties.Count());
                    ParsePropertyBag(context.SharedVariables, sb);
                }
               
                ASCIIEncoding encoder = new ASCIIEncoding();
                byte[] buffer = encoder.GetBytes(sb.ToString());

                clientStream.Write(buffer, 0, buffer.Length);
                clientStream.Flush();
                client.Close();

                client.Close();
            }
            catch { }
        }

        private void ParsePropertyBag(PropertyBag pb, StringBuilder sb)
        {
            pb.Properties.ToList().ForEach(p =>
            {
                sb.AppendFormat("+---{0}: {1} : {2}\r\n", p.Name, p.Value.GetType(), p.Value);

                // see if we can give the user a bit more information
                Type t = p.Value.GetType();
                if (t == typeof(DynamicEntity))
                {
                    DynamicEntity de = p.Value as DynamicEntity;
                    sb.AppendFormat("    +---: {0}\r\n", de.Name);
                    de.Properties.ToList().ForEach(prop =>
                    {
                        sb.AppendFormat("        |---{0} : {1} : {2}\r\n", prop.Name, prop.GetType(), de.ConvertToString(prop.Name));
                    });
                }
                if (t == typeof(Moniker))
                {
                    Moniker m = p.Value as Moniker;
                    sb.AppendFormat("    |---: {0} : {1}\r\n", m.Name, m.Id);
                }
                if (t == typeof(ColumnSet))
                {
                    ColumnSet c = p.Value as ColumnSet;
                    sb.AppendFormat("    |---: {0}\r\n", string.Join(", ", c.Attributes.Cast<string>().ToArray()));
                }
            });
        }
    }
}
